/*
 * Copyright (c) 2024 Huawei Device Co., Ltd.
 * Licensed under the Apache License, Version 2.0 (the "License");
 * you may not use this file except in compliance with the License.
 * You may obtain a copy of the License at
 *
 *     http://www.apache.org/licenses/LICENSE-2.0
 *
 * Unless required by applicable law or agreed to in writing, software
 * distributed under the License is distributed on an "AS IS" BASIS,
 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 * See the License for the specific language governing permissions and
 * limitations under the License.
 */

import * as path from 'path'
import {
  existsSync,
  mkdirSync,
  readdirSync,
  statSync,
  writeFileSync,
  readFileSync,
  rmdirSync,
  unlinkSync,
} from 'fs'
import { PluginConfig } from '../models'
import { logger } from './Logger'

// 文件管理类
export class FileManager {
  private config: PluginConfig;

  constructor(config: PluginConfig) {
    this.config = config;
  }

  // 获取目录下的文件
  getFiles(dir: string): string[] {
    const files: string[] = []
    if (!dir) {
      logger.warn('目录路径为空', 'FileManager')
      return []
    }
    
    if (!existsSync(dir)) {
      logger.warn(`目录不存在: ${dir}`, 'FileManager')
      return []
    }
    
    try {
      const fileArr = readdirSync(dir)
      if (fileArr && fileArr.length) {
        logger.debug(`扫描目录: ${dir}, 找到 ${fileArr.length} 个文件或目录`, 'FileManager')
        fileArr.forEach((file) => {
          const filePath = `${dir}/${file}`
          if (statSync(filePath).isDirectory()) {
            logger.debug(`发现子目录: ${filePath}`, 'FileManager')
            const arr = this.getFiles(filePath)
            files.push(...arr)
          } else {
            logger.debug(`添加文件: ${filePath}`, 'FileManager')
            files.push(filePath)
          }
        })
      } else {
        logger.debug(`目录为空: ${dir}`, 'FileManager')
      }
    } catch (err) {
      logger.error(`读取目录失败: ${dir}, 错误: ${err.message}`, 'FileManager')
    }
    
    return files
  }

  // 创建目录
  createDir(dir: string): void {
    if (!dir) {
      logger.warn('目录路径为空', 'FileManager')
      return
    }
    
    if (!existsSync(dir)) {
      try {
        mkdirSync(dir, { recursive: true })
        logger.debug(`创建目录: ${dir}`, 'FileManager')
      } catch (err) {
        logger.error(`创建目录失败: ${dir}, 错误: ${err.message}`, 'FileManager')
      }
    } else {
      logger.debug(`目录已存在: ${dir}`, 'FileManager')
    }
  }

  // 写入文件
  writeFile(filePath: string, content: string): void {
    if (!filePath) {
      logger.warn('文件路径为空', 'FileManager')
      return
    }
    
    try {
      writeFileSync(filePath, content, { encoding: 'utf8' })
      logger.debug(`写入文件: ${filePath}`, 'FileManager')
    } catch (err) {
      logger.error(`写入文件失败: ${filePath}, 错误: ${err.message}`, 'FileManager')
    }
  }

  // 读取文件
  readFile(filePath: string): string {
    if (!filePath) {
      logger.warn('文件路径为空', 'FileManager')
      return ''
    }
    
    if (!existsSync(filePath)) {
      logger.warn(`文件不存在: ${filePath}`, 'FileManager')
      return ''
    }
    
    try {
      const content = readFileSync(filePath, { encoding: 'utf8' })
      logger.debug(`读取文件: ${filePath}`, 'FileManager')
      return content
    } catch (err) {
      logger.error(`读取文件失败: ${filePath}, 错误: ${err.message}`, 'FileManager')
      return ''
    }
  }

  // 删除文件
  deleteFile(filePath: string): void {
    if (!filePath) {
      logger.warn('文件路径为空', 'FileManager')
      return
    }
    
    if (!existsSync(filePath)) {
      logger.debug(`文件不存在，无需删除: ${filePath}`, 'FileManager')
      return
    }
    
    try {
      unlinkSync(filePath)
      logger.debug(`删除文件: ${filePath}`, 'FileManager')
    } catch (err) {
      logger.error(`删除文件失败: ${filePath}, 错误: ${err.message}`, 'FileManager')
    }
  }

  // 删除目录
  deleteDir(dir: string): void {
    if (!dir) {
      logger.warn('目录路径为空', 'FileManager')
      return
    }
    
    if (!existsSync(dir)) {
      logger.debug(`目录不存在，无需删除: ${dir}`, 'FileManager')
      return
    }
    
    try {
      const files = readdirSync(dir)
      logger.debug(`删除目录: ${dir}, 包含 ${files.length} 个文件或子目录`, 'FileManager')
      
      files.forEach((file) => {
        const curPath = path.join(dir, file)
        if (statSync(curPath).isDirectory()) {
          this.deleteDir(curPath)
        } else {
          unlinkSync(curPath)
          logger.debug(`删除文件: ${curPath}`, 'FileManager')
        }
      })
      
      rmdirSync(dir)
      logger.debug(`目录已删除: ${dir}`, 'FileManager')
    } catch (err) {
      logger.error(`删除目录失败: ${dir}, 错误: ${err.message}`, 'FileManager')
    }
  }

  // 清理生成的文件和目录
  clean(): void {
    if (!this.config.modulePath) {
      logger.warn('模块路径为空，无法清理文件', 'FileManager')
      return
    }
    
    logger.info(`开始清理模块 ${this.config.moduleName} 的生成文件`, 'FileManager')
    
    // 删除生成的路由构建器文件和目录
    const builderDir = `${this.config.modulePath}/${this.config.builderDir}`
    this.deleteDir(builderDir)
    
    // 删除生成的路由映射文件和目录
    const routerMapDir = `${this.config.modulePath}/${this.config.routerMapDir}`
    if (existsSync(routerMapDir)) {
      // 只删除与当前模块相关的文件
      const moduleJsonFile = `${routerMapDir}/${this.config.moduleName}.json`
      const moduleTitleFile = `${routerMapDir}/${this.config.moduleName}_title.json`
      
      this.deleteFile(moduleJsonFile)
      this.deleteFile(moduleTitleFile)
      
      // 如果目录为空，则删除目录
      if (readdirSync(routerMapDir).length === 0) {
        this.deleteDir(routerMapDir)
      } else {
        logger.debug(`路由映射目录不为空，保留: ${routerMapDir}`, 'FileManager')
      }
    }
    
    logger.info(`模块 ${this.config.moduleName} 的生成文件已清理完成`, 'FileManager')
  }
} 